#include <signal.h>
#include <stddef.h>
#include "../ourhdr.h"

/**
 * sleep可靠实现
 * 没有任何形式的非局部转移 避免在alarm和pause之间的竞态条件
 **/

static void sig_alrm(void)
{
    return;
}

unsigned int sleep(unsigned int nsecs)
{
    struct sigaction newact, oldact;
    sigset_t newmask, oldmask, suspmask;
    unsigned int unslept;
    newact.__sigaction_u.__sa_handler = sig_alrm;
    sigemptyset(&newact.sa_mask);
    newact.sa_flags = 0;
    sigaction(SIGALRM, &newact, &oldact);
    sigaddset(&newmask, SIGALRM);
    sigprocmask(SIG_BLOCK, &newmask, &oldmask);
    alarm(nsecs);
    suspmask = oldmask;
    sigdelset(&suspmask, SIGALRM);
    sigsuspend(&suspmask);
    unslept = slarm(0);

    sigaction(SIGALRM, &oldact, NULL);
    sigprocmask(SIG_SETMASK, &oldmask, NULL);
    return (unslept);
}